<template>
	<view class="font-shrink-box" >
		<view class="content-borderbox" :style="openStauts?'height:auto;':'max-height:'+(line*(size+16))+'rpx;overflow: hidden;'" >
			<view class="content-text" :style="'line-height:'+(size+16)+'rpx;'">
				<text v-if="!openStauts">{{text}}</text>
				<text v-if="openStauts">{{oldText}}</text>
			</view>
			
		</view>
		<view class="ellipsis" v-if="isShowBtn">
			<view class="open-close-btn" :style="'font-size:' + btnSize + 'rpx'" @click.stop="showAll">
				<!-- 未展开时显示 "展开" + 向下箭头 -->
				<template v-if="!openStauts">
					<text class="btn-text">展开</text>
					<u-icon name="arrow-down" color="#EF852F" size="16" bold></u-icon>
				</template>
				<!-- 展开后显示 "收起" + 向上箭头 -->
				<template v-else>
					<text class="btn-text">收起</text>
					<u-icon name="arrow-up" color="#EF852F" size="16" bold></u-icon>
				</template>
			</view>
		</view>
	</view>
</template>

<script>
	export default {
		props:{
			line:{ //行数
				type:Number,
				default:3
			},
			text:{ // 文字
				type:String,
				default:''
			},
			size:{ //字体大小，单位rpx
				type:Number,
				default:32
			},
			btnSize:{
				type:Number,
				default:30
			},
			ellipsisBack:{ //省略号背景色
				type:String,
				default:'#fff'
			},
			hideEllips:{ //是否隐藏省略号
				type:Boolean,
				default:false
			}
		},
		data() {
			return {
				oldText: '', // 用于比较text prop是否变化
				borderHeight:0, //外层盒子的高度
				contentHeight:0, //放文字的盒子高度
				isShowBtn:false,//是否显示 展开/收起按钮
				openStauts:false,//展开状态,false-展开,true-收起
			};
		},
		watch: {
			text: {
				// 使用watch来监听text prop的变化，这比updated更精确
				handler(newVal) {
					if (newVal) {
						// 使用$nextTick确保DOM更新
						this.$nextTick(() => {
							// 增加一个短暂延时，给渲染引擎更多时间来完成布局计算，解决偶发性问题
							setTimeout(() => {
								this.initBtnShowStauts();
							}, 50); // 50毫秒通常足够
						});
					}
				},
				immediate: true, // 关键：组件首次加载时立即执行一次handler
				deep: true
			}
		},
		methods:{
			initBtnShowStauts(){
				// 记录旧文本，避免不必要的重复计算
				this.oldText = this.text; 
				
				const query = uni.createSelectorQuery().in(this);
				let p1 = new Promise((resolve)=>{
					query.select('.content-borderbox').fields({ size: true }, data => {
						// 容错处理，如果获取不到DOM则返回0
						resolve(data ? data.height : 0);
					}).exec();
				});
				let p2 = new Promise((resolve)=>{
					query.select('.content-text').fields({ size: true }, data => {
						resolve(data ? data.height : 0);
					}).exec();
				});
				
				Promise.all([p1, p2]).then((res)=>{
					this.borderHeight = res[0];
					this.contentHeight = res[1];
					// 核心判断逻辑：当内容高度大于容器限制高度时，显示按钮
					this.isShowBtn = this.borderHeight < this.contentHeight;
					
					// 如果文本内容刚好等于容器高度，也可能需要显示按钮（某些临界情况）
					// 为更健壮，可以加上一个小的容差
					if (!this.isShowBtn && Math.abs(this.borderHeight - this.contentHeight) < 2) {
						// 如果高度几乎相等，但文本长度很长，也认为需要展开
						if (this.text.length > (this.line * 25)) { // 25是一个估算值，每行大约25个字符
							this.isShowBtn = true;
						}
					}
				});
			},
			showAll(){
				this.openStauts = !this.openStauts;
			}
		}
	}
</script>

<style lang="scss">
	.font-shrink-box {
		width: 100%;
		.content-borderbox {
			font-size: 32rpx;
			position: relative;
		}
		.ellipsis {
			text-align: right;
			line-height: 1.5; // 增加行高，让按钮有足够的垂直空间
		}
		
		// --- 新增和修改的样式 ---
		.open-close-btn {
			display: inline-flex; // 使用 inline-flex 让容器宽度自适应内容
			align-items: center;  // 垂直居中对齐文字和图标
			justify-content: flex-end; // 确保在 .ellipsis 容器内靠右
			padding: 10rpx 0;
			color: #EF852F; // 统一设置颜色，会继承给内部的 <text>
			
			.btn-text {
				margin-right: 4rpx; // 在文字和图标之间添加一点间距
			}
		}
	}
</style>
